package com.iplant.wms.serviceImpl.dao.asn;

import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.po.excel.ExcelData;
import com.iplant.base.po.excel.ExcelLineData;
import com.iplant.base.po.excel.ExcelSheetData;
import com.iplant.base.utils.annotation.dao.DBBaseDAO;
import com.iplant.base.utils.cache.CacheUtils;
import com.iplant.base.utils.general.CalendarTool;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.BaseDAO;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.basic.service.po.mss.MSSMaterial;
import com.iplant.basic.service.po.mss.MSSUnit;
import com.iplant.wms.service.po.asn.WMSArrivalNoticeItem;
import com.iplant.wms.service.po.batch.MSSBatchRecord;
import com.iplant.wms.serviceImpl.dao.batch.MSSBatchRecordDAO;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@DBBaseDAO(WMSArrivalNoticeItem.class)
public class WMSArrivalNoticeItemDAO extends BaseDAO {


    private static WMSArrivalNoticeItemDAO Instance = null;

    private WMSArrivalNoticeItemDAO() {
        super("");
        this.Init();
    }


    public static WMSArrivalNoticeItemDAO getInstance() {
        if (Instance == null) {
            Instance = new WMSArrivalNoticeItemDAO();
        }
        return Instance;
    }


    /**
     * 删除集合
     *
     * @param wList
     */
    public void WMS_DeleteArrivalNoticeItemList(BMSEmployee wLoginUser, List<WMSArrivalNoticeItem> wList,
                                                OutResult<Integer> wErrorCode) {
        ServiceResult<Integer> wResult = new ServiceResult<Integer>(0);
        try {
            if (wList == null || wList.size() == 0) {
                return;
            }

            this.DeletePOList(wLoginUser, wList, wErrorCode);
            if (wErrorCode.Result != 0)
                return;

            List<Integer> wIDList = wList.stream().filter(p -> p.ID > 0).map(p -> p.ID).distinct().collect(Collectors.toList());

            WMSReceiveBillItemDAO.getInstance().WMS_DeleteReceiveBillItemListByArrivalNoticeItemIDList(wLoginUser, wIDList, wErrorCode);

            WMSInspectTaskDAO.getInstance().WMS_DeleteInspectTaskList(wLoginUser, wIDList, wErrorCode);


        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            log.error(ex.toString());
        }

    }


    /**
     * 删除集合
     */
    public void WMS_DeleteArrivalNoticeItem(BMSEmployee wLoginUser, List<Integer> wArrivalNoticeIDList,
                                            OutResult<Integer> wErrorCode) {
        try {
            if (wArrivalNoticeIDList == null || wArrivalNoticeIDList.size() == 0) {
                return;
            }

            this.Delete(StringUtils.Format("ArrivalNoticeID in ()",
                    StringUtils.Join(",", wArrivalNoticeIDList)), " and ID>0 ");

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            log.error("WMS_DeleteArrivalNoticeItemList", ex);
        }

    }

    /**
     * 删除集合
     */
    public void WMS_DeleteArrivalNoticeItem(BMSEmployee wLoginUser, WMSArrivalNoticeItem wWMSArrivalNoticeItem,
                                            OutResult<Integer> wErrorCode) {
        try {
            this.DeletePO(wLoginUser, wWMSArrivalNoticeItem, wErrorCode);

            if (wErrorCode.Result != 0)
                return;
            WMSReceiveBillItemDAO.getInstance().WMS_DeleteReceiveBillItemListByArrivalNoticeItemID(wLoginUser, wWMSArrivalNoticeItem.ID, wErrorCode);
            if (wErrorCode.Result != 0)
                return;
            if (wWMSArrivalNoticeItem.BatchRecordID > 0) {
                MSSBatchRecordDAO.getInstance().MSS_DeleteByID(wLoginUser, wWMSArrivalNoticeItem.BatchRecordID, wErrorCode);
            }

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            log.error("WMS_DeleteArrivalNoticeItemList", ex);
        }

    }


    /**
     * Excel数据解析-采购订单明细
     */
    public List<WMSArrivalNoticeItem> WMS_GetArrivalNoticeItemList(BMSEmployee wLoginUser, ExcelData wExcelData, OutResult<Integer> wErrorCode) {
        List<WMSArrivalNoticeItem> wResult = new ArrayList<WMSArrivalNoticeItem>();
        try {
            if (wExcelData.sheetData == null || wExcelData.sheetData.size() <= 1) {
                return wResult;
            }

            ExcelSheetData wSheetData = wExcelData.sheetData.get(1);
            if (wSheetData.lineData == null || wSheetData.lineData.size() == 0) {
                return wResult;
            }

            int wRow = 0;
            MSSUnit wMSSUnit;
            MSSMaterial wMSSMaterial;
            for (ExcelLineData wExcelLineData : wSheetData.lineData) {
                if (wRow == 0) {
                    wRow++;
                    continue;
                }

                String wPONo = wExcelLineData.colData.get(0);
                String wRowNo = wExcelLineData.colData.get(1);
                String wMaterialNo = wExcelLineData.colData.get(2);
                String wMaterialName = wExcelLineData.colData.get(3);
                String wNumber = wExcelLineData.colData.get(4);
                String wUnit = wExcelLineData.colData.get(5);
                String wPrice = wExcelLineData.colData.get(6);
                String wLott = wExcelLineData.colData.get(7);
                String wNotes = wExcelLineData.colData.get(8);

                WMSArrivalNoticeItem wWMSArrivalNoticeItem = new WMSArrivalNoticeItem();
                wWMSArrivalNoticeItem.ID = 0;
                wWMSArrivalNoticeItem.ArrivalNoticeCode = wPONo;
                wWMSArrivalNoticeItem.Code = wRowNo;
                wWMSArrivalNoticeItem.MaterialCode = wMaterialNo;
                wWMSArrivalNoticeItem.MaterialName = wMaterialName;
                wWMSArrivalNoticeItem.PackageRuleCode = wNumber;

                wWMSArrivalNoticeItem.ReceiveUnitText = wUnit;
                wMSSMaterial = CacheUtils.GetCacheInfo(MSSMaterial.class, -1, wMaterialNo);
                wWMSArrivalNoticeItem.MaterialID = wMSSMaterial.ID;
                wMSSUnit = CacheUtils.GetCacheInfo(MSSUnit.class, -1, wUnit);
                wWMSArrivalNoticeItem.ReceiveUnit = wMSSUnit.ID;
                wWMSArrivalNoticeItem.TotalPrice = StringUtils.parseDouble(wPrice);
                wWMSArrivalNoticeItem.ProductDate = StringUtils.parseCalendar(wLott);
                wWMSArrivalNoticeItem.Description = wNotes;

                wResult.add(wWMSArrivalNoticeItem);
            }
        } catch (Exception e) {
            log.error(e.toString());
            wErrorCode.Result = ExceptionTypes.Parameter.getValue();
        }
        return wResult;
    }

    /**
     * Excel数据解析-采购订单明细
     */
    public List<WMSArrivalNoticeItem> WMS_GetArrivalNoticeItemList(BMSEmployee wLoginUser, int wArrivalNoticeID, Pagination wPagination, OutResult<Integer> wErrorCode) {
        List<WMSArrivalNoticeItem> wResult = new ArrayList<WMSArrivalNoticeItem>();
        try {
            Map<String, Object> wParams = new HashMap<>();

            wParams.put("ArrivalNoticeID", wArrivalNoticeID);

            wResult = this.SelectPOList(wLoginUser, wParams, wPagination, wErrorCode);

        } catch (Exception e) {
            log.error(e.toString());
            wErrorCode.Result = ExceptionTypes.DBSQL.getValue();
        }
        return wResult;
    }


    public void WMS_UpdateArrivalNoticeFQTY(BMSEmployee wLoginUser, List<Integer> wIDList, OutResult<Integer> wErrorCode) {
        wErrorCode.set(0);
        try {
            String wSQLText = StringUtils.Format("update {0} t set t.ReceivedMaterialNumber= " +
                            "( select ifnull( sum(t2.StockFQTY),0) from {1} t2 WHERE t.ID=t2.ArrivalNoticeItemID) where  t.ID IN (2) ",
                    this.getTableName(), this.getTableName("wms_receivebillitem"), StringUtils.Join(",", wIDList));

            this.Update(wSQLText, new HashMap<>());
        } catch (Exception e) {
            wErrorCode.Result = ExceptionTypes.DBSQL.getValue();
            log.error("WMS_UpdateSalesDeliveryItemFQTY", e);
        }
    }


    /**
     * 批量保存收货单子项
     *
     * @param wLoginUser
     * @param wItemList
     * @param wErrorCode
     * @return
     */
    public void WMS_UpdateArrivalNoticeItemList(BMSEmployee wLoginUser, List<WMSArrivalNoticeItem> wItemList, OutResult<Integer> wErrorCode) {

        try {
            wErrorCode.set(0);

            if (wItemList.isEmpty()) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
            }

            for (WMSArrivalNoticeItem wItem : wItemList) {
                this.WMS_UpdateArrivalNoticeItem(wLoginUser, wItem, wErrorCode);
                if (wErrorCode.Result != 0) {
                    break;
                }
            }
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            log.error(ex.toString());
        }
    }

    /**
     * 添加或修改
     *
     * @param wLoginUser
     * @param wItem
     * @param wErrorCode
     * @return
     */
    public Integer WMS_UpdateArrivalNoticeItem(BMSEmployee wLoginUser, WMSArrivalNoticeItem wItem, OutResult<Integer> wErrorCode) {
        Integer wResult = 0;

        try {
            if (wItem == null) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return wResult;
            }

            if (StringUtils.isNotEmpty(wItem.BatchRuleCode)) {
                // 批次信息的新增或更新
                MSSBatchRecord wBatchRecord = new MSSBatchRecord();
                wBatchRecord.ID = wItem.BatchRecordID;
                wBatchRecord.Code = wItem.BatchRecordCode;
                wBatchRecord.ProductDate = wItem.ProductDate;
                wBatchRecord.ExpireDate = wItem.ExpireDate;
                wBatchRecord.StockDate = wItem.StockDate;
                wBatchRecord.LotAttr04 = wItem.LotAttr04;
                wBatchRecord.LotAttr05 = wItem.LotAttr05;
                wBatchRecord.LotAttr06 = wItem.LotAttr06;
                wBatchRecord.LotAttr07 = wItem.LotAttr07;
                wBatchRecord.LotAttr08 = wItem.LotAttr08;
                wBatchRecord.LotAttr09 = wItem.LotAttr09;
                wBatchRecord.LotAttr10 = wItem.LotAttr10;
                wBatchRecord.LotAttr11 = wItem.LotAttr11;
                wBatchRecord.LotAttr12 = wItem.LotAttr12;

                wBatchRecord.FactoryID = wItem.FactoryID;
                wBatchRecord.FactoryCode = wItem.FactoryCode;
                wBatchRecord.FactoryName = wItem.FactoryName;
                wBatchRecord.CustomerID = wItem.SupplierID;
                ; // 注意不同业务采用CustomerID or SupplierID
                wBatchRecord.CustomerCode = wItem.SupplierCode;
                wBatchRecord.CustomerName = wItem.SupplierName;

                wBatchRecord.MaterialID = wItem.MaterialID;
                wBatchRecord.MaterialNo = wItem.MaterialCode;
                wBatchRecord.MaterialName = wItem.MaterialName;

                wBatchRecord.RuleCode = wItem.BatchRuleCode;
                if (wBatchRecord.ProductDate == null) {
                    wBatchRecord.ProductDate = Calendar.getInstance();
                }
                if (wBatchRecord.ExpireDate == null) {
                    wBatchRecord.ExpireDate = CalendarTool.AddCalendar(Calendar.getInstance(), Calendar.YEAR, 10);
                }
                if (wBatchRecord.StockDate == null) {
                    wBatchRecord.StockDate = Calendar.getInstance();
                }


                MSSBatchRecordDAO.getInstance().UpdatePo(wLoginUser, wBatchRecord, wErrorCode);

                if (wErrorCode.Result != 0) {
                    return wResult;
                }
                if (wItem.BatchRecordID <= 0) {
                    wItem.BatchRecordID = wBatchRecord.ID;
                }
            }

            wItem.setUserInfo(wLoginUser);
            wResult = this.UpdatePo(wLoginUser, wItem, wErrorCode);
        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            log.error(ex.toString());
        }

        return wResult;
    }

}
